﻿' LibWowArmory
' by Ronald M. Clifford (roncli@roncli.com)
'
' This source code is released under the GNU Library General Public License (LGPL) Version 2.1.

Imports roncliProductions.LibWowArmory.Item.Tooltip
Imports System
Imports System.Globalization
Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.IO
Imports System.Linq
Imports System.Web
Imports System.Xml.Serialization

Namespace roncliProductions.LibWowArmory.Item.Info

    ''' <summary>
    ''' A class to get information on an item from the Armory
    ''' </summary>
    ''' <remarks></remarks>
    Public Class ItemInfo
        Inherits WowArmoryData

        Private iiPage As New Schema.page

#Region "Properties"

        ''' <summary>
        ''' The ID number of the item you wish to retrieve from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property ItemID As Integer

        ''' <summary>
        ''' The URL that will be used to retrieve the item from the Armory
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property URL As String
            Get
                Return String.Format(CultureInfo.InvariantCulture, "http://www.wowarmory.com/item-info.xml?i={0}", ItemID)
            End Get
        End Property

        ''' <summary>
        ''' Indicates to the inherited class that this request does not require login
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overrides ReadOnly Property RequiresLogin As Boolean
            Get
                Return False
            End Get
        End Property

        ''' <summary>
        ''' The costs associated with the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Cost As ItemCost
            Get
                Dim iItem As Schema.itemInfo_item = GetItem()
                If iItem.cost.Count = 0 Then
                    Return Nothing
                Else
                    Return (From c In iItem.cost Select New ItemCost(GetTokens(c), c.arena, c.buyPrice, CType(c.factionId, Enums.FactionType), c.honor, c.sellPrice)).First
                End If
            End Get
        End Property

        ''' <summary>
        ''' The random properties of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RandomProperties As Collection(Of RandomProperty)
            Get
                Dim rpProperties As Schema.randomProperties = GetRandomProperties()
                If rpProperties Is Nothing Then
                    Return New Collection(Of RandomProperty)
                Else
                    Return (From p In rpProperties.randomProperty Select New RandomProperty(p.suffix, GetRandomPropertyEnchants(p))).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' The skill rank required to disenchant the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property DisenchantLootSkillRank As Integer
            Get
                Dim dlDisenchantLoot As Schema.disenchantLoot = GetDisenchantLoot
                If dlDisenchantLoot Is Nothing Then
                    Return 0
                Else
                    Return dlDisenchantLoot.requiredSkillRank
                End If
            End Get
        End Property

        ''' <summary>
        ''' The items that the item can be disenchanted into
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property DisenchantLoot As Collection(Of DisenchantItem)
            Get
                Dim dlDisenchantLoot As Schema.disenchantLoot = GetDisenchantLoot()
                If dlDisenchantLoot Is Nothing Then
                    Return New Collection(Of DisenchantItem)
                Else
                    Dim strKey As String = String.Format(CultureInfo.InvariantCulture, "LibWowArmory.ItemInfo.{0}.DisenchantLoot", ItemID)
                    If Cache.Cache(strKey) Is Nothing Then
                        Dim diDisenchantItems As Collection(Of DisenchantItem) = (From i In dlDisenchantLoot.item Select New DisenchantItem(CType(i.dropRate, Enums.DropRateType), i.icon, i.id, i.level, i.maxCount, i.minCount, i.name, CType(i.quality, Enums.RarityType), i.type)).ToCollection

                        Cache.Cache.Insert(strKey, diDisenchantItems, Nothing, Date.UtcNow.AddDays(1), Nothing, Caching.CacheItemPriority.Normal, Nothing)

                        Return diDisenchantItems
                    Else
                        Return CType(Cache.Cache(strKey), Collection(Of DisenchantItem))
                    End If
                End If
            End Get
        End Property

        ''' <summary>
        ''' The quest that the item starts
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property StartsQuest As Quest
            Get
                Dim sqQuest As Schema.startsQuest = GetStartsQuest()
                If sqQuest Is Nothing Then
                    Return Nothing
                Else
                    Return (From q In sqQuest.quest Select New Quest(q.area, q.id, q.level, q.name, q.reqMinLevel, q.suggestedPartySize, q.type)).First
                End If
            End Get
        End Property

        ''' <summary>
        ''' The quests that the item is provided for
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ProvidedForQuests As Collection(Of Quest)
            Get
                Dim pfqQuests As Schema.providedForQuests = GetProvidedForQuests()
                If pfqQuests Is Nothing Then
                    Return New Collection(Of Quest)
                Else
                    Return (From q In pfqQuests.quest Select New Quest(q.area, q.id, q.level, q.name, q.reqMinLevel, q.suggestedPartySize, q.type)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' The quests that the item is an objective of
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ObjectiveOfQuests As Collection(Of Quest)
            Get
                Dim ooQuests As Schema.objectiveOfQuests = GetObjectiveOfQuests()
                If ooQuests Is Nothing Then
                    Return New Collection(Of Quest)
                Else
                    Return (From q In ooQuests.quest Select New Quest(q.area, q.id, q.level, q.name, q.reqMinLevel, q.suggestedPartySize, q.type)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' The quests that the item is a reward from
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RewardFromQuests As Collection(Of Quest)
            Get
                Dim rfqQuests As Schema.rewardFromQuests = GetRewardFromQuests()
                If rfqQuests Is Nothing Then
                    Return New Collection(Of Quest)
                Else
                    Return (From q In rfqQuests.quest Select New Quest(q.area, q.id, q.level, q.name, q.reqMinLevel, q.suggestedPartySize, q.type)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' The vendors that the item can be bought from
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Vendors As Collection(Of Creature)
            Get
                Dim vVendors As Schema.vendors = GetVendors()
                If vVendors Is Nothing Then
                    Return New Collection(Of Creature)
                Else
                    Return (From v In vVendors.creature Select New Creature(v.area, v.areaUrl, CType(v.classification, Enums.ClassificationType), CType(v.dropRate, Enums.DropRateType), If(v.heroic = 1, True, False), v.id, v.maxLevel, v.minLevel, v.name, v.title, v.type, v.url)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' The objects that the item can be found in
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ContainerObjects As Collection(Of ContainerObject)
            Get
                Dim coObjects As Schema.containerObjects = GetContainerObjects()
                If coObjects Is Nothing Then
                    Return New Collection(Of ContainerObject)
                Else
                    Return (From o In coObjects.object Select New ContainerObject(o.area, o.areaUrl, CType(o.dropRate, Enums.DropRateType), If(o.heroic = 1, True, False), o.id, o.name, o.url)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' The specific creatures the item drops from
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property DropSpecificCreatures As Collection(Of Creature)
            Get
                Dim dcDropCreatures As Schema.dropCreatures = GetDropCreatures()
                If dcDropCreatures Is Nothing Then
                    Return New Collection(Of Creature)
                Else
                    Return (From c In dcDropCreatures.creature Select New Creature(c.area, c.areaUrl, CType(c.classification, Enums.ClassificationType), CType(c.dropRate, Enums.DropRateType), If(c.heroic = 1, True, False), c.id, c.maxLevel, c.minLevel, c.name, c.title, c.type, c.url)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' A general description of creatures the item drops from
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property DropGeneralCreatures As CreatureInfo
            Get
                Dim dcDropCreatures As Schema.dropCreatures = GetDropCreatures()
                If dcDropCreatures Is Nothing Then
                    Return Nothing
                ElseIf dcDropCreatures.info.Count = 0 Then
                    Return Nothing
                Else
                    Return (From i In dcDropCreatures.info Select New CreatureInfo(GetAreaInfo(i), GetCreatureTypes(i), i.avgMaxLevel, i.avgMinLevel, i.maxLevel, i.minLevel)).First
                End If
            End Get
        End Property

        ''' <summary>
        ''' The specific creatures the item is pick pocketed from
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property PickPocketSpecificCreatures As Collection(Of Creature)
            Get
                Dim ppcPickPocketCreatures As Schema.pickPocketCreatures = GetPickPocketCreatures()
                If ppcPickPocketCreatures Is Nothing Then
                    Return New Collection(Of Creature)
                Else
                    Return (From c In ppcPickPocketCreatures.creature Select New Creature(c.area, c.areaUrl, CType(c.classification, Enums.ClassificationType), CType(c.dropRate, Enums.DropRateType), If(c.heroic = 1, True, False), c.id, c.maxLevel, c.minLevel, c.name, c.title, c.type, c.url)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' A general description of creatures the item is pick pocketed from
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property PickPocketGeneralCreatures As CreatureInfo
            Get
                Dim ppcPickPocketCreatures As Schema.pickPocketCreatures = GetPickPocketCreatures()
                If ppcPickPocketCreatures Is Nothing Then
                    Return Nothing
                ElseIf ppcPickPocketCreatures.info.Count = 0 Then
                    Return Nothing
                Else
                    Return (From i In ppcPickPocketCreatures.info Select New CreatureInfo(GetAreaInfo(i), GetCreatureTypes(i), i.avgMaxLevel, i.avgMinLevel, i.maxLevel, i.minLevel)).First
                End If
            End Get
        End Property

        ''' <summary>
        ''' The specific creatures the item is skinned from, via skinning or engineering
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property SkinSpecificCreatures As Collection(Of Creature)
            Get
                Dim scSkinCreatures As Schema.skinCreatures = GetSkinCreatures
                If scSkinCreatures Is Nothing Then
                    Return New Collection(Of Creature)
                Else
                    Return (From c In scSkinCreatures.creature Select New Creature(c.area, c.areaUrl, CType(c.classification, Enums.ClassificationType), CType(c.dropRate, Enums.DropRateType), If(c.heroic = 1, True, False), c.id, c.maxLevel, c.minLevel, c.name, c.title, c.type, c.url)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' A general description of creatures the item is skinned from, via skinning or engineering
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property SkinGeneralCreatures As CreatureInfo
            Get
                Dim scSkinCreatures As Schema.skinCreatures = GetSkinCreatures()
                If scSkinCreatures Is Nothing Then
                    Return Nothing
                ElseIf scSkinCreatures.info.Count = 0 Then
                    Return Nothing
                Else
                    Return (From i In scSkinCreatures.info Select New CreatureInfo(GetAreaInfo(i), GetCreatureTypes(i), i.avgMaxLevel, i.avgMinLevel, i.maxLevel, i.minLevel)).First
                End If
            End Get
        End Property

        ''' <summary>
        ''' The specific creatures the item is herbed from
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property HerbSpecificCreatures As Collection(Of Creature)
            Get
                Dim hcHerbCreatures As Schema.herbCreatures = GetHerbCreatures()
                If hcHerbCreatures Is Nothing Then
                    Return New Collection(Of Creature)
                Else
                    Return (From c In hcHerbCreatures.creature Select New Creature(c.area, c.areaUrl, CType(c.classification, Enums.ClassificationType), CType(c.dropRate, Enums.DropRateType), If(c.heroic = 1, True, False), c.id, c.maxLevel, c.minLevel, c.name, c.title, c.type, c.url)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' A general description of creatures the item is herbed from
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property HerbGeneralCreatures As CreatureInfo
            Get
                Dim hcHerbCreatures As Schema.herbCreatures = GetHerbCreatures()
                If hcHerbCreatures Is Nothing Then
                    Return Nothing
                ElseIf hcHerbCreatures.info.Count = 0 Then
                    Return Nothing
                Else
                    Return (From i In hcHerbCreatures.info Select New CreatureInfo(GetAreaInfo(i), GetCreatureTypes(i), i.avgMaxLevel, i.avgMinLevel, i.maxLevel, i.minLevel)).First
                End If
            End Get
        End Property

        ''' <summary>
        ''' The specific creatures the item is mined from
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property MineSpecificCreatures As Collection(Of Creature)
            Get
                Dim mcMineCreatures As Schema.mineCreatures = GetMineCreatures()
                If mcMineCreatures Is Nothing Then
                    Return New Collection(Of Creature)
                Else
                    Return (From c In mcMineCreatures.creature Select New Creature(c.area, c.areaUrl, CType(c.classification, Enums.ClassificationType), CType(c.dropRate, Enums.DropRateType), If(c.heroic = 1, True, False), c.id, c.maxLevel, c.minLevel, c.name, c.title, c.type, c.url)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' A general description of creatures the item is mined from
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property MineGeneralCreatures As CreatureInfo
            Get
                Dim mcMineCreatures As Schema.mineCreatures = GetMineCreatures()
                If mcMineCreatures Is Nothing Then
                    Return Nothing
                ElseIf mcMineCreatures.info.Count = 0 Then
                    Return Nothing
                Else
                    Return (From i In mcMineCreatures.info Select New CreatureInfo(GetAreaInfo(i), GetCreatureTypes(i), i.avgMaxLevel, i.avgMinLevel, i.maxLevel, i.minLevel)).First
                End If
            End Get
        End Property

        ''' <summary>
        ''' The spell that creates the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property CreatedBy As SpellReagents
            Get
                Dim cbCreatedBy As Schema.createdBy = GetCreatedBy()
                If cbCreatedBy Is Nothing Then
                    Return Nothing
                Else
                    Return (From s In cbCreatedBy.spell Select New SpellReagents(GetCreatedBySpellReagents(s), s.Icon, s.id, s.name)).First
                End If
            End Get
        End Property

        ''' <summary>
        ''' The spell that the item is a reagent for
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ReagentFor As Collection(Of SpellItem)
            Get
                Dim rfReagentFor As Schema.reagentFor = GetReagentFor()
                If rfReagentFor Is Nothing Then
                    Return New Collection(Of SpellItem)
                Else
                    Return (From s In rfReagentFor.spell Select New SpellItem(GetSpellCreatedItem(s), GetReagentForSpellReagents(s), s.Icon, s.id, s.name)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' The items that can be bought with this item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property CurrencyFor As Collection(Of CurrencyItem)
            Get
                Dim cfCurrencyFor As Schema.currencyFor = GetCurrencyFor()
                If cfCurrencyFor Is Nothing Then
                    Return New Collection(Of CurrencyItem)
                Else
                    Return (From i In cfCurrencyFor.item Select New CurrencyItem(GetCurrencyItemCost(i), i.icon, i.id, i.level, i.name, CType(i.quality, Enums.RarityType), i.requiredSkill, i.requiredSkillRank, i.type)).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' The filename of the icon of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Icon As String
            Get
                Return GetItem.icon
            End Get
        End Property

        ''' <summary>
        ''' The level of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Level As Integer
            Get
                Return GetItem.level
            End Get
        End Property

        ''' <summary>
        ''' Determines whether or not the item is a quest item that drops for everyone in the party
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property MultiLoot As Boolean
            Get
                Return GetItem.multiLoot = 1
            End Get
        End Property

        ''' <summary>
        ''' Determines whether or not the item is an item that starts a quest and drops for everyone in the party
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property MultiLootQuest As Boolean
            Get
                Return GetItem.multiLootQuest = 1
            End Get
        End Property

        ''' <summary>
        ''' The name of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Name As String
            Get
                Return GetItem.name
            End Get
        End Property

        ''' <summary>
        ''' The quality of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Quality As Enums.RarityType
            Get
                Return CType(GetItem.quality, Enums.RarityType)
            End Get
        End Property

        ''' <summary>
        ''' The required ability to use the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredAbility As String
            Get
                Return GetItem.requiredAbility
            End Get
        End Property

        ''' <summary>
        ''' The required profession to use the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredSkill As String
            Get
                Return GetItem.requiredSkill
            End Get
        End Property

        ''' <summary>
        ''' The required skill level to use the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property RequiredSkillRank As Integer
            Get
                Return GetItem.requiredSkillRank
            End Get
        End Property

        ''' <summary>
        ''' The type of the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property ItemType As String
            Get
                Return GetItem.type
            End Get
        End Property

        ''' <summary>
        ''' The faction that can use the item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>A return of FactionType.None indicates there are no faction restrictions</remarks>
        Public ReadOnly Property FactionRestriction As Enums.FactionType
            Get
                If GetItem.translationFor.Count = 0 Then
                    Return Enums.FactionType.None
                Else
                    Select Case GetItem.translationFor.First.factionEquiv
                        Case 0
                            Return Enums.FactionType.Horde
                        Case 1
                            Return Enums.FactionType.Alliance
                    End Select
                End If
            End Get
        End Property

        ''' <summary>
        ''' The items that are equivalent for the other faction to this item
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property TranslationFor As Collection(Of TranslationForItem)
            Get
                Dim tfTranslationFor As Schema.translationFor = GetTranslationFor()
                If tfTranslationFor Is Nothing Then
                    Return New Collection(Of TranslationForItem)
                Else
                    Return (From i In tfTranslationFor.item Select New TranslationForItem(CType(tfTranslationFor.factionEquiv, Enums.FactionType), i.icon, i.id, i.level, i.name, CType(i.quality, Enums.RarityType))).ToCollection
                End If
            End Get
        End Property

        ''' <summary>
        ''' Gets the item's tooltip information, containing more detailed information about the item itself
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property GetItemTooltip As ItemTooltip
            Get
                Return New ItemTooltip(ItemID)
            End Get
        End Property

#End Region

#Region "Public Methods"

        ''' <summary>
        ''' Constructor to load an item with a known ID number
        ''' </summary>
        ''' <param name="intID"></param>
        ''' <remarks></remarks>
        Public Sub New(ByVal intID As Integer)
            ItemID = intID
            Load()
        End Sub

        ''' <summary>
        ''' Loads the item from the Aarmory
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Load()
            Dim strKey As String = String.Format(CultureInfo.InvariantCulture, "LibWowArmory.ItemInfo.{0}", ItemID)
            If Cache.Cache(strKey) Is Nothing Then
                MyBase.Retrieve()

                Dim xsSerializer As New XmlSerializer(iiPage.GetType)

                Using srXML As New StringReader(MyBase.Data)
                    iiPage = CType(xsSerializer.Deserialize(srXML), Schema.page)
                End Using

                Cache.Cache.Insert(strKey, iiPage, Nothing, Date.UtcNow.AddDays(1), Nothing, Caching.CacheItemPriority.Normal, Nothing)
            Else
                iiPage = CType(Cache.Cache(strKey), Schema.page)
            End If

            If iiPage.itemInfo Is Nothing Then
                Throw New ArgumentException("The item you are trying to retrieve does not exist.")
            End If
            If iiPage.itemInfo.First.item Is Nothing Then
                Throw New ArgumentException("The item you are trying to retrieve does not exist.")
            End If
        End Sub

#End Region

#Region "Private Methods"

        Private Function GetItems() As Collection(Of Schema.itemInfo_item)
            Return (From p In iiPage.itemInfo Where p.item.Count > 0 Select p.item.First).ToCollection
        End Function

        Private Function GetItem() As Schema.itemInfo_item
            Return GetItems.First
        End Function

        Private Function GetCost() As Schema.cost
            Dim varCost = (From i In GetItems Where i.cost.Count > 0 Select i.cost.First)
            If varCost.Count = 0 Then
                Return Nothing
            Else
                Return varCost.First
            End If
        End Function

        Private Function GetRandomProperties() As Schema.randomProperties
            Dim varRandomProperties = (From i In GetItems Where i.randomProperties.Count > 0 Select i.randomProperties.First)
            If varRandomProperties.Count = 0 Then
                Return Nothing
            Else
                Return varRandomProperties.First
            End If
        End Function

        Private Function GetDisenchantLoot() As Schema.disenchantLoot
            Dim varDisenchantLoot = (From i In GetItems Where i.disenchantLoot.Count > 0 Select i.disenchantLoot.First)
            If varDisenchantLoot.Count = 0 Then
                Return Nothing
            Else
                Return varDisenchantLoot.First
            End If
        End Function

        Private Function GetStartsQuest() As Schema.startsQuest
            Dim varStartsQuest = (From i In GetItems Where i.startsQuest.Count > 0 Select i.startsQuest.First)
            If varStartsQuest.Count = 0 Then
                Return Nothing
            Else
                Return varStartsQuest.First
            End If
        End Function

        Private Function GetProvidedForQuests() As Schema.providedForQuests
            Dim varProvidedForQuests = (From i In GetItems Where i.providedForQuests.Count > 0 Select i.providedForQuests.First)
            If varProvidedForQuests.Count = 0 Then
                Return Nothing
            Else
                Return varProvidedForQuests.First
            End If
        End Function

        Private Function GetObjectiveOfQuests() As Schema.objectiveOfQuests
            Dim varObjectiveOfQuests = (From i In GetItems Where i.objectiveOfQuests.Count > 0 Select i.objectiveOfQuests.First)
            If varObjectiveOfQuests.Count = 0 Then
                Return Nothing
            Else
                Return varObjectiveOfQuests.First
            End If
        End Function

        Private Function GetRewardFromQuests() As Schema.rewardFromQuests
            Dim varRewardFromQuests = (From i In GetItems Where i.rewardFromQuests.Count > 0 Select i.rewardFromQuests.First)
            If varRewardFromQuests.Count = 0 Then
                Return Nothing
            Else
                Return varRewardFromQuests.First
            End If
        End Function

        Private Function GetVendors() As Schema.vendors
            Dim varVendors = (From i In GetItems Where i.vendors.Count > 0 Select i.vendors.First)
            If varVendors.Count = 0 Then
                Return Nothing
            Else
                Return varVendors.First
            End If
        End Function

        Private Function GetContainerObjects() As Schema.containerObjects
            Dim varContainerObjects = (From i In GetItems Where i.containerObjects.Count > 0 Select i.containerObjects.First)
            If varContainerObjects Is Nothing OrElse varContainerObjects.Count = 0 Then
                Return Nothing
            Else
                Return varContainerObjects.First
            End If
        End Function

        Private Function GetDropCreatures() As Schema.dropCreatures
            Dim varDropCreatures = (From i In GetItems Where i.dropCreatures.Count > 0 Select i.dropCreatures.First)
            If varDropCreatures.Count = 0 Then
                Return Nothing
            Else
                Return varDropCreatures.First
            End If
        End Function

        Private Function GetPickPocketCreatures() As Schema.pickPocketCreatures
            Dim varPickPocketCreatures = (From i In GetItems Where i.pickPocketCreatures.Count > 0 Select i.pickPocketCreatures.First)
            If varPickPocketCreatures.Count = 0 Then
                Return Nothing
            Else
                Return varPickPocketCreatures.First
            End If
        End Function

        Private Function GetSkinCreatures() As Schema.skinCreatures
            Dim varSkinCreatures = (From i In GetItems Where i.skinCreatures.Count > 0 Select i.skinCreatures.First)
            If varSkinCreatures.Count = 0 Then
                Return Nothing
            Else
                Return varSkinCreatures.First
            End If
        End Function

        Private Function GetHerbCreatures() As Schema.herbCreatures
            Dim varHerbCreatures = (From i In GetItems Where i.herbCreatures.Count > 0 Select i.herbCreatures.First)
            If varHerbCreatures.Count = 0 Then
                Return Nothing
            Else
                Return varHerbCreatures.First
            End If
        End Function

        Private Function GetMineCreatures() As Schema.mineCreatures
            Dim varMineCreatures = (From i In GetItems Where i.mineCreatures.Count > 0 Select i.mineCreatures.First)
            If varMineCreatures.Count = 0 Then
                Return Nothing
            Else
                Return varMineCreatures.First
            End If
        End Function

        Private Function GetCreatedBy() As Schema.createdBy
            Dim varCreatedBy = (From i In GetItems Where i.createdBy.Count > 0 Select i.createdBy.First)
            If varCreatedBy.Count = 0 Then
                Return Nothing
            Else
                Return varCreatedBy.First
            End If
        End Function

        Private Function GetReagentFor() As Schema.reagentFor
            Dim varReagentFor = (From i In GetItems Where i.reagentFor.Count > 0 Select i.reagentFor.First)
            If varReagentFor.Count = 0 Then
                Return Nothing
            Else
                Return varReagentFor.First
            End If
        End Function

        Private Function GetCurrencyFor() As Schema.currencyFor
            Dim varCurrencyFor = (From i In GetItems Where i.currencyFor.Count > 0 Select i.currencyFor.First)
            If varCurrencyFor.Count = 0 Then
                Return Nothing
            Else
                Return varCurrencyFor.First
            End If
        End Function

        Private Shared Function GetTokens(ByVal cCost As Schema.cost) As Collection(Of TokenCost)
            If cCost.token Is Nothing Then
                Return New Collection(Of TokenCost)
            Else
                Return (From t In cCost.token Select New TokenCost(t.count, t.icon, t.id)).ToCollection
            End If
        End Function

        Private Shared Function GetRandomPropertyEnchants(ByVal rpProperty As Schema.randomProperty) As Collection(Of String)
            If rpProperty.randomPropertyEnchant Is Nothing Then
                Return New Collection(Of String)
            Else
                Return (From e In rpProperty.randomPropertyEnchant Select e.name).ToCollection
            End If
        End Function

        Private Shared Function GetAreaInfo(ByVal iInfo As Schema.info) As Collection(Of AreaInfo)
            If iInfo.area Is Nothing Then
                Return New Collection(Of AreaInfo)
            Else
                Return (From a In iInfo.area Select New AreaInfo(a.id, a.name)).ToCollection
            End If
        End Function

        Private Shared Function GetCreatureTypes(ByVal iinfo As Schema.info) As Collection(Of CreatureType)
            If iinfo.type Is Nothing Then
                Return New Collection(Of CreatureType)
            Else
                Return (From t In iinfo.type Select New CreatureType(t.id, t.name)).ToCollection
            End If
        End Function

        Private Shared Function GetCreatedBySpellReagents(ByVal cbsSpell As Schema.createdBy_spell) As Collection(Of Reagent)
            If cbsSpell.reagent Is Nothing Then
                Return New Collection(Of Reagent)
            Else
                Return (From r In cbsSpell.reagent Select New Reagent(r.count, r.icon, r.id, r.name)).ToCollection
            End If
        End Function

        Private Shared Function GetReagentForSpellReagents(ByVal rfsSpell As Schema.reagentFor_spell) As Collection(Of Reagent)
            If rfsSpell.reagent Is Nothing Then
                Return New Collection(Of Reagent)
            Else
                Return (From r In rfsSpell.reagent Select New Reagent(r.count, r.icon, r.id, r.name)).ToCollection
            End If
        End Function

        Private Shared Function GetSpellCreatedItem(ByVal rfsSpell As Schema.reagentFor_spell) As SpellCreatedItem
            If rfsSpell.item Is Nothing Then
                Return Nothing
            Else
                Return (From i In rfsSpell.item Select New SpellCreatedItem(i.icon, i.id, i.level, i.name, CType(i.quality, Enums.RarityType), i.requiredAbility, i.requiredSkill, i.requiredSkillRank, i.type)).First
            End If
        End Function

        Private Shared Function GetCurrencyItemCost(ByVal cfiItem As Schema.currencyFor_item) As ItemCost
            If cfiItem.cost Is Nothing Then
                Return Nothing
            Else
                Return (From c In cfiItem.cost Select New ItemCost(GetTokens(c), c.arena, c.buyPrice, CType(c.factionId, Enums.FactionType), c.honor, c.sellPrice)).First
            End If
        End Function

        Private Function GetTranslationFor() As Schema.translationFor
            If GetItem.translationFor.Count = 0 Then
                Return Nothing
            Else
                Return GetItem.translationFor.First
            End If
        End Function

#End Region

    End Class

End Namespace